package com.daxiasoftware.xxx.controller;

import java.util.Date;
import java.util.Iterator;
import java.util.Map;
import java.util.TreeMap;

import javax.servlet.http.HttpServletRequest;
import javax.servlet.http.HttpServletResponse;

import org.apache.commons.lang3.builder.ToStringBuilder;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.stereotype.Controller;
import org.springframework.transaction.annotation.Transactional;
import org.springframework.web.bind.annotation.RequestMapping;

import com.alipay.api.AlipayApiException;
import com.alipay.api.AlipayClient;
import com.alipay.api.DefaultAlipayClient;
import com.alipay.api.domain.AlipayTradeWapPayModel;
import com.alipay.api.internal.util.AlipaySignature;
import com.alipay.api.request.AlipayTradeWapPayRequest;
import com.baomidou.mybatisplus.mapper.EntityWrapper;
import com.daxiasoftware.alipay.config.AlipayConfig;
import com.daxiasoftware.xxx.entity.Pay;
import com.daxiasoftware.xxx.entity.enums.PayStatus;
import com.daxiasoftware.xxx.entity.enums.PayType;
import com.daxiasoftware.xxx.exception.BizException;

@Controller
@RequestMapping(value = "alipay")
public class AlipayController extends BaseController {

	@Autowired
	private AlipayConfig alipayConfig;
	
	/**
	 * 跳到支付信息页面，让用户填写金额等
	 * @return
	 * @throws Exception
	 */
	@RequestMapping("payInfo")
	public String payInfo() throws Exception {
		System.out.println(ToStringBuilder.reflectionToString(alipayConfig));
		return "alipay/alipay_payInfo";
	}
	
	/**
	 * 提交支付信息，然后生成签名之类的，
	 * 跳到jsp页面生成form表单，然后自动提交form表单
	 * @return
	 * @throws Exception
	 */
	@Transactional
	@RequestMapping("submitPayInfo")
	public String submitPayInfo(HttpServletRequest request2, HttpServletResponse response, Map<String, Object> map, Double amount) throws Exception {
		if (amount == null || amount <= 0) {
			throw new BizException("请输入正确的充值金额");
		}
		Date now = new Date();
		
		// 商户订单号，商户网站订单系统中唯一订单号，必填
	    String out_trade_no = "A" + System.currentTimeMillis();
		// 订单名称，必填
	    String subject = "用户充值";
		System.out.println(subject);
	    // 付款金额，必填
	    String total_amount=amount + "";
	    // 商品描述，可空
	    String body = "用户充值";
	    // 超时时间 可空
	   String timeout_express="2m";
	    // 销售产品码 必填
	    String product_code="QUICK_WAP_PAY";
	    
	    Pay pay = new Pay();
	    pay.setAmount(amount);
	    pay.setCreateTime(now);
	    pay.setOrderNo(out_trade_no);
	    pay.setOutOrderNo(out_trade_no);
	    pay.setStatus(PayStatus.NotPay.getValue());
	    pay.setType(PayType.Wxpay.getValue());
	    payService.insert(pay);
	    
	    /**********************/
	    // SDK 公共请求类，包含公共请求参数，以及封装了签名与验签，开发者无需关注签名与验签     
	    //调用RSA签名方式
	    AlipayClient client = new DefaultAlipayClient(alipayConfig.getURL(), alipayConfig.getAPPID(), alipayConfig.getRSA_PRIVATE_KEY(), alipayConfig.getFORMAT(), alipayConfig.getCHARSET(), alipayConfig.getALIPAY_PUBLIC_KEY(),alipayConfig.getSIGNTYPE());
	    AlipayTradeWapPayRequest alipay_request=new AlipayTradeWapPayRequest();
	    
	    // 封装请求支付信息
	    AlipayTradeWapPayModel model=new AlipayTradeWapPayModel();
	    model.setOutTradeNo(out_trade_no);
	    model.setSubject(subject);
	    model.setTotalAmount(total_amount);
	    model.setBody(body);
	    model.setTimeoutExpress(timeout_express);
	    model.setProductCode(product_code);
	    alipay_request.setBizModel(model);
	    // 设置异步通知地址
	    alipay_request.setNotifyUrl(alipayConfig.getNotify_url());
	    // 设置同步地址
	    // alipay_request.setReturnUrl(alipayConfig.getReturn_url());   
	    // alipay_request.setReturnUrl("http://localhost:8080/alipay/return");
	    alipay_request.setReturnUrl("http://erp.daxiasoftware.com/alipay/return");
	    
	    // form表单生产
	    String form = "";
		try {
			// 调用SDK生成表单
			form = client.pageExecute(alipay_request).getBody();
			map.put("form", form);
		} catch (AlipayApiException e) {
			e.printStackTrace();
		} 
		return "alipay/alipay_submitPayInfo";
	}

	@Transactional
	@RequestMapping("return")
	public String returnMethod(HttpServletRequest request, Map<String, Object> map) throws Exception {
		//获取支付宝GET过来反馈信息
		Map<String,String> params = new TreeMap<String,String>();
		Map requestParams = request.getParameterMap();
		for (Iterator iter = requestParams.keySet().iterator(); iter.hasNext();) {
			String name = (String) iter.next();
			String[] values = (String[]) requestParams.get(name);
			String valueStr = "";
			for (int i = 0; i < values.length; i++) {
				valueStr = (i == values.length - 1) ? valueStr + values[i]
						: valueStr + values[i] + ",";
			}
			//System.out.println(name + ": " + valueStr);
			//乱码解决，这段代码在出现乱码时使用。如果mysign和sign不相等也可以使用这段代码转化
			valueStr = new String(valueStr.getBytes("ISO-8859-1"), "utf-8");
			params.put(name, valueStr);
		}
		System.out.println("maps: ");
		for (String key : params.keySet()) {
			System.out.println(key + ": " + params.get(key));
		}
		//获取支付宝的通知返回参数，可参考技术文档中页面跳转同步通知参数列表(以下仅供参考)//
		//商户订单号

		String out_trade_no = new String(request.getParameter("out_trade_no").getBytes("ISO-8859-1"),"UTF-8");

		//支付宝交易号

		String trade_no = new String(request.getParameter("trade_no").getBytes("ISO-8859-1"),"UTF-8");
		System.out.println("publickey:" + alipayConfig.getALIPAY_PUBLIC_KEY());
		//获取支付宝的通知返回参数，可参考技术文档中页面跳转同步通知参数列表(以上仅供参考)//
		//计算得出通知验证结果
		//boolean verify_result = AlipaySignature.rsaCheckV1(params, alipayConfig.getALIPAY_PUBLIC_KEY(), alipayConfig.getCHARSET());
		boolean verify_result = AlipaySignature.rsaCheckV1(params, alipayConfig.getALIPAY_PUBLIC_KEY(), alipayConfig.getCHARSET(), "RSA2");
		
		Pay pay = payService.selectOne(new EntityWrapper<Pay>().eq("order_no", out_trade_no).and().eq("status", PayStatus.NotPay.getValue()));
		pay.setResponseTime(new Date());
		if(verify_result){//验证成功
			//////////////////////////////////////////////////////////////////////////////////////////
			//请在这里加上商户的业务逻辑程序代码
			//该页面可做页面美工编辑
			//——请根据您的业务逻辑来编写程序（以上代码仅作参考）——
			System.out.println("验证成功");
			//////////////////////////////////////////////////////////////////////////////////////////
			map.put("result", "支付成功");
			pay.setStatus(PayStatus.Success.getValue());
			payService.updateById(pay);
			return "redirect:/alipay/result?success=true";
		}else{
			//该页面可做页面美工编辑
			//out.clear();
			//out.println("验证失败");
			System.out.println("验证失败");
			map.put("result", "支付失败");
			pay.setStatus(PayStatus.Failed.getValue());
			payService.updateById(pay);
			return "redirect:/alipay/result?success=false";
		}
		
	}
	
	@RequestMapping("result")
	public String result(Boolean success, Map<String, Object> map) throws Exception {
		map.put("msg", success ? "支付成功" : "支付失败");
		return "alipay/alipay_result";
	}
}
